/*
 * cfg.c
 *
 *  Created on: Mar 2, 2011
 *      Author: root
 */

#include "../includes.h"


st_ip_cfg_file_ sicf={
				//0
				//, 0           1		    2			3		 4		5			   6		7	     8
				{"address" ,"netmask" ,"broadcast" ,"gateway" ,"sn" ,"remoteip" ,"remoteport" ,"id","sourceport",NULL,}
				,
};

char *str_ipcfg_default_str=
		"auto lo\n"
		"iface lo inet loopback\n"
		"auto eth0\n"
		"iface eth0 inet static\n\n";


void Init_cfg()
{
	Debug_Halt(31);
	char *s= read_rst_info();
	Debug_Halt(32);
	if( s[0] == 'R' ) iUdpReset = 1; //Reset by UDP
	else if( s[0] == 'S' ) iUdpReset = 2; //Reset by System/Reset command
	Debug_Halt(33);
	write_rst_info("Normal");
	mac_str[0]=0;

}

void SystemResetCall()
{
	iCntResetFlag = 3;
	write_rst_info("SystemReset");
}

void set_user_cfg(char* key, char *v)
{
	int i;
	st_ip_cfg_file_ *p=&sicf;
	lower_str(key); //lower_str(v);
	for(i=0;i<M_sicf_MAX_COUNT && p->key[i]!=NULL ; i++){
			if( strcmp( p->key[i] ,key)==0 ){
				strcpy( p->v[i] ,v );
				udp_printf( "Set>>%d,%s %s" ,i ,p->key[i] ,p->v[i] );
				break;
			}
	}

}
void init_user_cfg()
{
	strcpy(sicf.v[M_IP_CFG_Source_PORT_INDEX],"12002");
}
void read_user_cfg()
{

	FILE *fp;
	int cnt,i;
	st_ip_cfg_file_ *p=&sicf;
	char t1[M_sicf_MAX_CONTENT],t2[M_sicf_MAX_CONTENT];
	fp = fopen( M_IP_CFG_FILE_NAME,"rt");
	if( !fp ){
		udp_printf("open error: 1 st\n");
		fp = fopen( M_IP_CFG_LINUX_FILE_NAME,"rt");
		if( !fp ){
			udp_printf("open error: 2 nd\n")
			return ;
		}
	}

	for(i=0;i<M_sicf_MAX_COUNT && p->key[i]!=NULL ; i++){ p->v[i][0]=(char)0; } //p->count=0;}

	while( (cnt=fscanf(fp,"%s %s\n" ,t1 ,t2)) > 0 )
	{
		lower_str(t1); //lower_str(t2);
		for(i=0;i<M_sicf_MAX_COUNT && p->key[i]!=NULL ; i++){
			if( strcmp(p->key[i],t1)==0 ){
				strcpy(p->v[i],t2);
				udp_printf("%d,%s %s\n" ,i ,p->key[i] ,p->v[i] );
				//p->count++;
				break;
			}
		}
	}
	fclose(fp);
}

static char *argv[16];

char *delimit2nd = "\n";
int Parse_Args2nd(char *cmdline, char **argv)
{
	char *tok;
	int argc = 0;

	argv[argc] = NULL;

	//for(tok = strtok(cmdline, delimit); tok && argc<16; tok = strtok(NULL, delimit))
	for(tok = strtok(cmdline, delimit2nd); tok && argc<16; tok = strtok(NULL, delimit2nd))
		{
		argv[argc++] = tok;
	}

	return argc;
}

void read_user_cfg_str(char *buf)
{
	FILE *fp;
	char *str=buf;
	int argc,i,j,cnt;
	char t1[M_sicf_MAX_CONTENT],t2[M_sicf_MAX_CONTENT];
	st_ip_cfg_file_ *p=&sicf;
	udp_printf("===================\n");
	while(*str)
	{
		if( *str == M_IP_CFG_PARSING_CHAR 	) *str='\n';
		if( *str == M_IP_CFG_SPACE_CHAR 	) *str=' ';
		str++;
	}

	argc = Parse_Args2nd(buf, argv);
	udp_printf("======= %d =========\n",argc);
	int found;
	for( j=0; j<argc; j++ ){
		if( (cnt=sscanf(argv[j],"%s %s\n",t1,t2)) ==2 )
		{
			found = 0;
			lower_str(t1); //lower_str(t2);
			for(i=0;i<M_sicf_MAX_COUNT && p->key[i]!=NULL ; i++){
				if( strcmp(p->key[i],t1)==0 ){
					strcpy(p->v[i],t2);
					found = 1;
					udp_printf("comRead>> %d,%s %s\n",i,p->key[i],p->v[i] );
					break;
				}
			}
			if( !found ) udp_printf("not found >>%d,%s\n",i, t1 );
		}
		else udp_printf("error>>i)%d, argc)%d\n",j,cnt);
	}
	//, 0           1		    2			3		 4		5			   6		7
	//{"address" ,"netmask" ,"broadcast" ,"gateway" ,"sn" ,"remoteip" ,"remoteport" ,"id",NULL,}

//	if( strlen(p->v[i]) > 10 ) {
//		sprintf(t1,"ifconfig eth0 %d.%d.%d.%d",)
//	}

	udp_printf("===================\n");
}

char buf_temp_usr_cfg[1000];
char* make_user_cfg_str()
{
	int cnt,i;
	char t[200];
	st_ip_cfg_file_ *p=&sicf;

	buf_temp_usr_cfg[0]=0;
	for(i=0; p->key[i]!=NULL; i++)
	{
		sprintf(t,"%s %s$",p->key[i], p->v[i] );
		strcat(buf_temp_usr_cfg,t);
	}
	//strcat(buf_temp_usr_cfg,"\n");
	return buf_temp_usr_cfg;
}

void write_user_cfg()
{
	FILE *fp;
	int i;
	st_ip_cfg_file_ *p=&sicf;

	printf("start:W:user_cfg \n");

	fp = fopen( M_IP_CFG_FILE_NAME_W,"wt");
	if( !fp ){ udp_printf("W:user_cfg>>Open error\n"); return ; }

	//for(i=0; i<p->count; i++)
	for(i=0; p->key[i]!=NULL; i++)
	{
		fprintf(fp,"%s %s\n",p->key[i], p->v[i] );
		udp_printf("W>>%d,%s %s\n",i,p->key[i],p->v[i] );
	}
	fclose(fp);
}

void write_ip_cfg()
{
	FILE *fp;
	int i;

	st_ip_cfg_file_ *p=&sicf;

	udp_printf("start:W:ip_cfg-- \n");
	fp = fopen( M_IP_CFG_LINUX_FILE_NAME,"wt");
	if( !fp ){ udp_printf("W:ip_cfg>>Open error\n"); return ; }

	fprintf(fp,str_ipcfg_default_str);
	//for(i=0; i<p->count && i<M_scif_LINUX_CFG_CNT; i++)
	for(i=0; p->key[i]!=NULL && i<M_scif_LINUX_CFG_CNT; i++)
	{
		fprintf(fp,"%s %s\n",p->key[i], p->v[i] );
		udp_printf("LW>>%d,%s %s\n",i,p->key[i],p->v[i] );
	}
	fclose(fp);
}


int  ExecShellCmd(char *cmd)
{
struct stat st;

	switch (fork()) {
		case -1:
				return -1;
	   		break;

		case 0:
			set_lowest_sched();

			usleep(10000);

			if (setsid()<0) {
				LogItString(LOG_CATA1_NORM, LOG_CATA2_FAIL, "ExecShellCmd 1");
				child_calling_exit = 1;
				exit(EXIT_SUCCESS);
			}

			usleep(10000);

			child_calling_exit = 1;

			execl("/bin/sh", "sh", "-c", cmd, NULL);
			exit(EXIT_SUCCESS);
			break;

		default:
			//fwup_do_fork(state, reason);
			break;
	}
	return 1;
}


char mac_str[M_SIZE_HWADDR_STR+1];
void GetIPconfig(int ii,char *str)
{
	FILE *fp;
	int cnt ,i ,macaddr[6]={0,};
	char t1[100]; //, t2[M_SIZE_HWADDR_STR+1];
	char *p;
	int found = 0;

	fp = fopen( M_IPCONFIG_TEMP_FILE_NAME,"rt");
	if( !fp ){
		udp_printf("ifcfg:open error: 1 st\n");
		return ;
	}

	//while( (cnt=fscanf(fp,"%s\n" ,t1)) > 0 )
	while( (fgets(t1,100,fp)) != NULL )
	{
		udp_printf("> %s\n",t1);
		if( ii == ip_cfg_MAC && (p = strstr(t1,M_str_HWAddr))!=NULL ){
			strncpy(mac_str,(char*)(p+sizeof(M_str_HWAddr)-1) ,M_SIZE_HWADDR_STR);
			mac_str[M_SIZE_HWADDR_STR] = 0;
			udp_printf("========found>>%s<<\n",mac_str);
			if( sscanf(mac_str, "%x:%x:%x:%x:%x:%x",
					&macaddr[0],&macaddr[1],&macaddr[2],&macaddr[3],&macaddr[4],&macaddr[5]) == 6)
			{
				for(i=0; i<6;i++){
					str[i] = (char)macaddr[i];
					udp_printf("0x%02X ",str[i]&0xFF);
				}
				udp_printf("\n");
			}
			found = 1;
			break;
		}
	}
	udp_printf("end\n");
	if( !found ) iIfcofigCnt = 3;
	fclose(fp);


}

#define file_name_reset_info	"/gpsclock/rst.info"
char rst_info[100+1];
void write_rst_info(char *s)
{
	FILE *fp;
	int i;

	fp = fopen( file_name_reset_info,"wt");
	if( !fp ){ udp_printf("W:"file_name_reset_info">>Open error\n"); return ; }

	fprintf(fp,s);

	fclose(fp);
}

char* read_rst_info()
{
	FILE *fp;
	fp = fopen( file_name_reset_info,"rt");
	if( !fp ){
		udp_printf("open error: "file_name_reset_info"\n");
		strcpy(rst_info,"Normal");
	}
	else{
		fgets(rst_info,100,fp);
		fclose(fp);
	}
	return rst_info;
}

extern char **environ;

//int child_calling_exit = 0;
void shell_do_fork(char *cmd)
{


	set_lowest_sched();

	//sched_yield();
	usleep(10000);

//	dup2(fwup_pipe[1], STDOUT_FILENO);
//	dup2(fwup_pipe[1], STDERR_FILENO);
//	close(fwup_pipe[0]);
	//dup2(fwup_ptyp_wr, STDOUT_FILENO);
	//dup2(fwup_ptyp_wr, STDERR_FILENO);
	//sched_yield();
	usleep(10000);

	if (setsid()<0) {
		child_calling_exit = 1;
		exit(EXIT_SUCCESS);
	}

	//sched_yield();
	usleep(10000);

	memset(cmd,0,256);
	//sprintf(cmd,"gzip -d %s 2>&1 && echo %s", FWUPD_ZIPED_FILE_NAME, ECHO_GUNZIP_OK_MSG);

	//sched_yield();
	usleep(10000);

	child_calling_exit = 1;
	//execl("/bin/sh", "sh", "-c", cmd, NULL);
	execle("/bin/sh", "sh", "-c", cmd, NULL, environ);

	exit(EXIT_SUCCESS);
}

int grcafw_exist()
{
	FILE *fp;
	fp = fopen( M_DL_FILE_NAME_ORIGIN,"rt");
	if( !fp ){
		return 0;
	}
	else{
		fclose(fp);
		return 1;
	}
}

int iMonitorPHYNotAlive = 0;
int bMonitorPHY = 1;
void MonitorPHYAlive()
{

	if( (phy_get_regs(0x19)&0x1F)!=0x03 ){
		if( (iMonitorPHYNotAlive % 10) == 0){
			if( iMonitorPHYNotAlive == 0 ) LogItString(LOG_CATA1_NORM, LOG_CATA2_WARN, "Reset PHY");
			if( 1 || bMonitorPHY ){
				printf("\nAssertResetToPHY\n");
				AssertResetToPHY();
			}
		}
		iMonitorPHYNotAlive++;
	}
	else{
		if( iMonitorPHYNotAlive > 0 )LogItString(LOG_CATA1_NORM, LOG_CATA2_OK, "PHY is Good");
		iMonitorPHYNotAlive = 0;
	}
	//printf(">>%d:0x%X(%d)\n",iMonitorPHYNotAlive,(phy_get_regs(0x19)&0x1F),bMonitorPHY);
}

int iCntPeriodUdpReport = 0;
int iCntResetFlag = 0;
//int iPeriodUdpReport = 30;
int iIfcofigCnt=5;
int iUdpReset=0;
int iFWUpdate=0;
int iCntPeriodHeartBeat = M_DEFINE_START_VALUE+1;
//int iPeriodHeartBeat=1;
int16u total_crc_saved;
void SetUdpMsg()
{
	IPC_Data_T *pIn;
	pIn = &udp.msg.in;
	MonitorPHYAlive();
	SetUpdMsgValue();
	AssignAlarm();

	if( !bInitUdp  ) return; // in case that udp port is not opened yet! wait...

	//////////////////////////////////////////
	//-----Report status power,reset,period
	if( iCntPeriodUdpReport == M_DEFINE_START_VALUE){
		//msg_pack_data_report2nd( &udp ,-1 ,iCntPeriodUdpReport );
		if( iUdpReset ==1 ){
			msg_pack_data_report2nd( &udp ,-1 ,3 ); iUdpReset=0;
			//udp_printf("init: reset report 3\n");
		}
		else if( iUdpReset ==2 ){
			msg_pack_data_report2nd( &udp ,-1 ,4 ); iUdpReset=0;
			//udp_printf("init: reset report 4\n");
		}
		else{
			msg_pack_data_report2nd( &udp ,-1 ,2 ); iUdpReset=0;
			//udp_printf("init: reset report 2\n");
		}
		//iCntPeriodUdpReport = M_DEFINE_START_VALUE;
	}
	else if( iCntPeriodUdpReport > CONFIG.iPeriodUdpReport*60 + M_DEFINE_START_VALUE ){
		if( !DuringDownloading() )  msg_pack_data_report2nd( &udp ,-1 ,0 );
		iCntPeriodUdpReport = M_DEFINE_START_VALUE+1;
	}
	iCntPeriodUdpReport++;

	//////////////////////////////////////////
	//-----Reboot at reset command
	if( iCntResetFlag == 1){
		ExecShellCmd("reboot");
	}
	if( iCntResetFlag > 0 ){
		udp_printf("--- iCntResetFlag:%d\n",iCntResetFlag);
		iCntResetFlag--;
	}

	//////////////////////////////////////////
	//-----issue ifconfig to get mac address
	if( GC.RunningTime > 5 && iIfcofigCnt > 0 ){ iIfcofigCnt=0; 	ExecShellCmd("ifconfig >/if.txt"); }
	//if( iIfcofigCnt > 0 ) iIfcofigCnt--;

	//////////////////////////////////////////
	//-----report alarm at alarm change
	if( bAlarmFalg ){
		if( iAlarmUdpReport>0 ) iAlarmUdpReport--;
		if( iAlarmUdpReport <10 ){ bAlarmFalg = 0; iAlarmUdpReport=0; }
		else if( iAlarmUdpReport%10 == 0 ){
			if( !DuringDownloading() ) msg_pack_data_alarm(&udp,-1);
			udp_printf("msg_pack_data_alarm:%d\n",iAlarmUdpReport);
		}

	}

	//////////////////////////////////////////
	//-----issue fw update command at completion of transfer file.
	if( iFWUpdate > 0 ){
		switch(iFWUpdate)
		{
			case 10:
				unlink(M_DL_FILE_NAME_ORIGIN);
				ExecShellCmd("cp -f "M_DL_FILE_NAME_WR" ./grcafw.gz");
				udp_printf("\n========== 10: copy\n");
				break;
			case 9:
				ExecShellCmd("gzip -d grcafw.gz");
				udp_printf("\n========== 9: gzip -d grcafw.gz\n");
				break;
			case 7:
				if( grcafw_exist() ){
					unlink(M_DL_FILE_NAME_ORIGIN);
					msg_pack_download_complete_rsp(&udp,pIn->ipc.sequence,total_crc_saved,1);
					udp_printf("\n========== 7: grcafw_exist\n");
					break;
				}
				else{
					//msg_pack_download_complete_rsp(&udp,pIn->ipc.sequence,p2->total_crc,0);
					msg_pack_download_complete_rsp(&udp,pIn->ipc.sequence,0x0000,0);
					
					iFWUpdate = 1; // in case of error Stop Ucompress & Reboot
					udp_printf("\n========== 7: grcafw_Not...exist\n");
					break;
				}
				
			case 6:
				ExecShellCmd("pwd >/gpsclock/pwd.txt");
				break;
				//ExecShellCmd("cp -f "M_DL_FILE_NAME_WR" /grcafw.gz");
			case 5:
				ExecShellCmd("cp -f "M_DL_FILE_NAME_WR" ./grcafw.gz");
				break;
			case 3:
				ExecShellCmd("upg-grca-fw  grcafw.gz");
				udp_printf("\n========== 3: upg-grca-fw  grcafw.gz\n");
				break;
			case 1:
				iCntResetFlag = 6;
				break;
		}
		iFWUpdate--;
	}

	//////////////////////////////////////////
	//---- Send HeartBeat
	if( iCntPeriodHeartBeat == M_DEFINE_START_VALUE && CONFIG.iPeriodHeartBeat!=0 ){
		if( !DuringDownloading() )msg_pack_data_heartbeat();
	}
	else if( (iCntPeriodHeartBeat > CONFIG.iPeriodHeartBeat*60 + M_DEFINE_START_VALUE) && CONFIG.iPeriodHeartBeat!=0 ){
		if( !DuringDownloading() )msg_pack_data_heartbeat();
		iCntPeriodHeartBeat = M_DEFINE_START_VALUE+1;
	}
	iCntPeriodHeartBeat++;

	/////////
	// download timeout
	if( iTimeOutDownload > 0) iTimeOutDownload --;
	else{
		iTimeOutDownload = 0;
	}
}

